package core;

import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Point2D;

import towers.Tower;

public class Mouse extends MouseAdapter implements MouseMotionListener {
	
	private Tower selectedItem;
	private Model model;
	private Point mouseDot = new Point();
	
	public Mouse( Model model ){
		this.model = model;
	}
	
	private boolean clickedInField( Point p  ){
		return ( p.x < Model.battlefieldWidth && 
				p.y < Model.battlefieldHeight );
	}
	
	/**
	 * Gaat mousepoint doorgeven aan een model class
	 */
	public void mouseClicked( MouseEvent e ){
		Point p = e.getPoint();
		if (e.getButton() == MouseEvent.BUTTON1) {
			/**
			 *  moet naar (een)  model
			 */
			//als er in het veld geklikt is
			if( clickedInField( p ) ){
				//als er voorheen een tower geselecteerd is
				if( this.selectedItem != null ){
					//als de vorige toren op het veld staat
					if( this.selectedItem.position != null ){
						//als waar je nu op klikt een toren is
						if( this.getTowerByPoint( p ) != null ){
							//de toren waar op geklikt is 
							this.selectedItem = this.getTowerByPoint( p );
							//notify mijn obeservers maar eens lekker goed
							this.model.notifyObservers( "new tower selected" );
							model.repaint();
						} else {
							//null want je klikte nergens op
							this.selectedItem = null;
							model.repaint();
							
						}
					}
					//de toren wie voorheen geselecteerd is heeft geen punten
					//dit staat dus voor een nieuw te bouwen toren
					else {
						if( !this.placeOccupied( p ) ){
							
							//omdat de tower in het midden moet komen als je hem ergens wilt bouwe
							p.x -= selectedItem.getSize().getWidth() / 2;
							p.y -= selectedItem.getSize().getHeight() / 2;
							
							if( model.buyTower( selectedItem, new Point2D.Double((double)p.x, (double)p.y) ) ){
								this.selectedItem = null;
								System.out.println( "Nieuwe tower gebouwd" );
							}						
						}
						else {
							System.out.println( "Hier bouwen is niet toegestaan" );
						}
					} // als er geen last selected item is
				}else{
					if( this.getTowerByPoint( p ) != null ){
						//de toren waar op geklikt is 
						this.selectedItem = this.getTowerByPoint( p );
						//notify mijn obeservers maar eens lekker goed
						this.model.notifyObservers( "new tower selected" );
						model.repaint();
					} else {
						//null want je klikte nergens op
						this.selectedItem = null;
						model.repaint();
					}
				}
			}
		}else if (e.getButton() == MouseEvent.BUTTON3) {
			selectedItem = null;
			model.repaint();
		}
	}
	
	public Tower getSelectedItem(){
		return this.selectedItem;
	}
	
	public void setSelectedItem( Tower t ){
		this.selectedItem = t;
	}
			
	public boolean placeOccupied( Point p ){
		for( Tower t : model.getTowers() ){
			//omdat de toren wordt gebouw waar je klikt (midden) moet er links en rechts
			//de helft van de toren beschikbaar zijn
			if( t.bounds.intersects( p.x-(selectedItem.getSize().getWidth()/2), p.y-(selectedItem.getSize().getHeight()/2), selectedItem.getSize().getWidth(), selectedItem.getSize().getHeight())){
				return true;
			}
		}
		if( isOnRoad(p) || isOnBase(p) || !isInField(p) ){
			return true;
		}
		return false;
	}
	
	private boolean isOnRoad( Point p){
		for(Polygon y : model.getMap().getPolygonArray()){
			if(y.intersects((p.x-selectedItem.image.getIconWidth()/2), (p.y - selectedItem.image.getIconHeight()/2), selectedItem.image.getIconWidth(), selectedItem.image.getIconHeight() )){
				return true;
			}
		}
		return false;
		//return model.getMap().getPolygon().intersects(p.x, p.y, selectedItem.image.getIconWidth(), selectedItem.image.getIconHeight() );
	}
	
	private boolean isOnBase(Point p){
		return model.getMap().getBase().getBounds().intersects((p.x-selectedItem.image.getIconWidth()/2), (p.y - selectedItem.image.getIconHeight()/2), selectedItem.image.getIconWidth(), selectedItem.image.getIconHeight());
	}
	
	private boolean isInField( Point p ){
		if( p.x >= (selectedItem.getSize().getWidth() / 2) && p.y >= (selectedItem.getSize().getHeight() / 2) && p.x < (Model.battlefieldWidth - selectedItem.getSize().getWidth() / 2) && p.y < (Model.battlefieldHeight - selectedItem.getSize().getHeight() / 2) )
			return true;
		
		return false;
	
	}
	
	public Tower getTowerByPoint( Point p ){
		for( Tower t : model.getTowers() ){
			if( t.bounds.intersects( p.x, p.y, 5, 5 ) ){
				return t;
			}
		}
		
		return null;
	}
	
	public boolean checkNewTower(){
		return ( this.selectedItem.position == null );
	}
	
	public Point getClickLocation(){
		return new Point();
	}
	
    public void mouseMoved(MouseEvent e) {
    	//controleren of er een geselecteerde toren is, die nog niet geplaatst is.
		if( getSelectedItem() != null && getSelectedItem().position == null ){
			//het punt van de mouse updaten en tekenen
			mouseDot = e.getPoint();
			model.repaint();
		}else{
			//zorgen dat het punt uit beeld is bij niet bestaande of reeds gebouwde toren.
			mouseDot.x = 900;
			mouseDot.y = 900;
		}
    }
    
    public Point getMouseDot(){
    	return mouseDot;
    }
}
